/*   
 * Copyright (c) 2011, TUgether, TU Braunschweig
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
 /**
 * @author Mohamed Karray <mohamed.karray@gmx.de>
 *
 */
 

package de.tu_bs.tugether.liferayunit.liferayElements;

import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

import de.tu_bs.tugether.liferayunit.exceptions.LiferayElementNotFoundException;
import de.tu_bs.tugether.liferayunit.exceptions.LiferayPropertyKeyNotFoundException;
import de.tu_bs.tugether.liferayunit.liferayPages.LiferayPage;
import de.tu_bs.tugether.liferayunit.util.LiferayUtil;

public abstract class LiferayElement {

	private HtmlElement htmlElement;
	private String id;
	private Properties properties;
	protected  Logger logger ;
	private LiferayPage liferayPage;
	
	public LiferayElement(HtmlElement htmlElement, LiferayPage lfrPage) throws IOException,
			LiferayElementNotFoundException {
		this.liferayPage = lfrPage;
		this.htmlElement = htmlElement;
		this.properties = new Properties();
		logger = Logger.getLogger(this.getClass());
		logger.addAppender(LiferayUtil.appender);
		InputStream propertyFile = LiferayUtil.getProprtyFile(this.getClass()
				.getSimpleName() + ".properties");
		this.properties.load(propertyFile);
		this.addImportedProperties(properties);
		this.id= htmlElement.getId();
		initialize();
	}

	private void addImportedProperties(Properties prop) throws IOException {
		String importFile = prop.getProperty("import");
		if (importFile != null) {

			Properties importetdProperties = new Properties();

			InputStream propertyFile = LiferayUtil.getProprtyFile(importFile);

			importetdProperties.load(propertyFile);
			for (Object key : importetdProperties.keySet()) {
				if (key.toString() != "import") {
					this.properties.put(key,
							importetdProperties.getProperty((String) key));
				} else {
					this.addImportedProperties(importetdProperties);
				}

			}
		}
	}

	protected abstract void initialize() throws LiferayElementNotFoundException;
	
	protected void initializeElementAndPage() throws Exception {
		HtmlPage currentPage = (HtmlPage) getLiferayPage().getWebClient().getCurrentWindow().getEnclosedPage();
		getLiferayPage().setPage(currentPage);
		this.initialize();
		getLiferayPage().initialize();
	}
	public <T extends HtmlElement> T getHtmlElement() {
		return (T) htmlElement;
	}

	public void setHtmlElement(HtmlElement htmlElement) {
		this.htmlElement = htmlElement;
	}

	public LiferayPage getLiferayPage() {
		return liferayPage;
	}

	public void setLiferayPage(LiferayPage liferayPage) {
		this.liferayPage = liferayPage;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Properties getProperties() {
		return properties;
	}

	public void setProperties(Properties properties) {
		this.properties = properties;
	}

	protected String getXPath(String key, Object... objects) {
		String p = properties.getProperty(key);
		logger.debug("getFirstByXPathKey p=" + p);
		if (objects.length == 0){
			return p;
		}
		String xpath = MessageFormat.format(p, objects);
		logger.debug("getFirstByXPathKey xpath=" + xpath);
		return xpath;
	}

	protected List<?> getByXPathKey(String key, Object... objects) throws LiferayPropertyKeyNotFoundException,
			LiferayElementNotFoundException {
		String xPath = getXPath(key, objects);
		if (xPath == null) {
			throw new LiferayPropertyKeyNotFoundException("key: '" + key + "' not found in the Properties file: '"
					+ this.getClass().getSimpleName() + ".properties'");
		} else {
			List<?> result = this.htmlElement.getByXPath(xPath);
			if (result == null)
				throw new LiferayElementNotFoundException("Das gesuchte HTML-Element mit dem Key: '"+key+"' wurde nicht gefunden");
			else {
				return result;
			}
		}
	}

	protected <T extends HtmlElement> T getFirstByXPathKey(String key, Object... objects)
			throws LiferayPropertyKeyNotFoundException, LiferayElementNotFoundException {
		String xPath = getXPath(key, objects);
		if (xPath == null) {
			throw new LiferayPropertyKeyNotFoundException("key: '" + key + "' not found in the Properties file: '"
					+ this.getClass().getSimpleName() + ".properties'");
		} else {
			Object element = this.htmlElement.getFirstByXPath(xPath);
			if (element == null)
				throw new LiferayElementNotFoundException("Das gesuchte HTML-Element mit dem Key: '"+key+"' wurde nicht gefunden");
			else {
				return (T) element;
			}
		}
	}

	protected boolean findElementWithXPathKey(String key){
		try {
			this.getFirstByXPathKey(key);
			return true;
		} catch (LiferayElementNotFoundException e) {
			return false;
		} catch (LiferayPropertyKeyNotFoundException e) {
			e.printStackTrace();
			return false;
		}
	}
	public String toString() {
		return "Element of type: " + this.getClass()
				+ " \n it represent the html element: " + htmlElement.toString();

	}

}
